﻿#define TEST

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SAPBoAddon.B1Assistant;
using System.Windows.Forms;
using System.Resources;
using System.Collections;
using System.Diagnostics;
using System.Configuration;
using System.Text.RegularExpressions;


namespace BoAddonBiz_FreightForwarder.UpLoad
{
    /// <summary>
    /// 附件上传公用类
    /// </summary>
    internal class Common_UpLoad
    {
        #region  辅助成员
        SAPbouiCOM.Application SBOApp;
        SAPbobsCOM.Company SBOCompany;
        public string ServerIP { get; set; }
        public string UserID { get; set; }
        public string Password { get; set; }
        public string ServerUpLoadFilePath { get; set; }
        #endregion

        #region 构造方法
        public Common_UpLoad()
        {
            SBOApp = SAPBoAddon.B1Addon.B1Addon.SBOApp;
            SBOCompany = SAPBoAddon.B1Addon.B1Addon.SBOCompany;
#if DEBUG && TEST
            ServerIP = "127.0.0.1";
            UserID = "Administrator";
            Password = "thinkpad";
#else

            ServerIP = ConfigurationManager.AppSettings["ServerIP"];
            UserID = ConfigurationManager.AppSettings["ServerUserName"];
            Password = ConfigurationManager.AppSettings["ServerUserPwd"];
            ServerUpLoadFilePath = ConfigurationManager.AppSettings["UpLoadFilePath"];
#endif
        }

        #endregion

        #region  功能函数
        /// <summary>
        /// 上传文件到服务器
        /// </summary>
        public void Uploading(SAPbouiCOM.Form oForm, string DataTable)
        {
            try
            {
#if DEBUG
                DateTime dt1 = DateTime.Now;
#endif
                #region 服务器初始化
                string DocEntry = string.Empty;
                string UpLoadFileName = string.Empty;
                string ServerPath = string.Empty;
                string ClientPath = string.Empty;
                #endregion
                DocEntry = oForm.DataSources.UserDataSources.Item("LastEntry").Value;
                SAPbobsCOM.Recordset ors = SBOCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.BoRecordset);
                SAPbouiCOM.DBDataSource dbds = oForm.DataSources.DBDataSources.Item(DataTable);

                /*上传所有行*/
                for (int i = 0; i < dbds.Size; i++)
                {
                    dbds.Offset = i;
                    ClientPath = dbds.GetValue("U_LocalPath", i).Trim();
                    ServerPath = dbds.GetValue("U_FilePath", i).Trim();
                    if (string.IsNullOrEmpty(ClientPath))
                    {
                        continue;
                    }
                    if (!System.IO.File.Exists(ClientPath))
                    {
                        throw new Exception("选中文件路径异常，请重新选择...");
                    }
                    UpLoadFileName = ClientPath.Substring(ClientPath.LastIndexOf(@"\") + 1);

                    #region 拼接命令字符串
                    //打开连接
                    ConnectionServer();
                    //Copy文件
                    CopyFile(ClientPath, ServerPath);
                    //关闭连接
                    CloseConection();
                    #endregion
                    #region 本地中不保存
                    ors.DoQuery("UPDATE [" + DataTable + "] SET U_LocalPath = null Where DocEntry = " + dbds.GetValue("DocEntry", i).Trim() + " And LineId = " + dbds.GetValue("LineId", i).Trim());
                    dbds.SetValue("U_LocalPath", i, "");
                    #endregion
                }
#if DEBUG
                TimeSpan ts = DateTime.Now - dt1;
                SBOApp.SetStatusBarMessage("附件上传耗时：" + ts.TotalMilliseconds.ToString(), SAPbouiCOM.BoMessageTime.bmt_Short, false);
#endif
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Copy文件
        /// </summary>
        /// <param name="Source">原地址</param>
        /// <param name="Destination">目标地址</param>
        private void CopyFile(string Source, string Destination)
        {
            try
            {
                string Error = string.Empty;
                string Result = string.Empty;
                string Command = string.Empty;
                Command = "MD \"" + Destination.Substring(0, Destination.LastIndexOf('\\')) + "\"";
                FileUploading.Execute(Command, 60 * 1000, out Result, out Error);
                Command = "copy \"" + Source + "\" \"" + Destination + "\"  /y";
                FileUploading.Execute(Command, 60 * 1000, out Result, out Error);
                if (Result.Trim() == "登录失败: 未知的用户名或错误密码。")
                {
                    ConnectionServer();
                    FileUploading.Execute(Command, 60 * 1000, out Result, out Error);
                }
                if (string.IsNullOrEmpty(Result.Trim()) && string.IsNullOrEmpty(Error.Trim()) == false)
                {
                    SBOApp.SetStatusBarMessage("上传失败；错误信息：" + Error, SAPbouiCOM.BoMessageTime.bmt_Short, true);
                    CloseConection();
                    throw (new Exception("上传失败；错误信息：" + Error));
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        private bool _Connected = false;
        /// <summary>
        /// 连接状态
        /// </summary>
        public bool Connected
        {
            get { return _Connected; }
            set { _Connected = value; }
        }
        /// <summary>
        /// 打开服务器连接
        /// </summary>
        /// <param name="ServerIP"></param>
        /// <param name="ServerPassword"></param>
        /// <param name="ServerUserId"></param>
        private void ConnectionServer()
        {
            string Command = "net use \\\\" + ServerIP + "\\ipc$ \"" + Password + "\" /u:\"" + UserID + "\"";
            string Error = string.Empty;
            string Result = string.Empty;
            FileUploading.Execute(Command, 60 * 1000, out Result, out Error);
            if (Result.Trim() == "命令成功完成。" && string.IsNullOrEmpty(Error.Trim()))
            {
                Connected = true;
                return;
            }
            if (string.IsNullOrEmpty(Error.Trim()) == false)
            {
                string Error2 = string.Empty;
                FileUploading.Execute("net use", 60 * 1000, out Result, out Error2);
                Regex reg = new Regex(@"(?<=OK\s+)[.\S]*?(?=\s+Microsoft)");
                MatchCollection matches = reg.Matches(Result);
                if (matches.Count <= 0)
                {
                    Connected = false;
                    throw new Exception("网络问题导致文件上传失败，错误信息：" + Error);
                }
            }
        }
        /// <summary>
        /// 关闭服务器连接
        /// </summary>
        /// <param name="ServerIP"></param>
        private void CloseConection()
        {
            string Command = string.Empty;
            string Error = string.Empty;
            string Result = string.Empty;
            if (Connected)
            {
                Command = "net use \\\\" + ServerIP + "\\ipc$ /del /y";
                FileUploading.Execute(Command, 60 * 1000, out Result, out Error);
                if (string.IsNullOrEmpty(Result.Trim()) == false && string.IsNullOrEmpty(Error.Trim()))
                {
                    Connected = false;
                    return;
                }
            }

        }
        #region 文件下载
        /// <summary>
        ///文件下载
        /// </summary>
        public void DownFile(SAPbouiCOM.Form oForm, string DataTable, int Offset)
        {
            try
            {

                #region 服务器初始化
                SAPbouiCOM.DBDataSource dbds;
                string Command = string.Empty;
                string UpLoadFileName = string.Empty;
                string FileName = string.Empty;
                string ServerPath = string.Empty;
                string FilePath = string.Empty;
                #endregion
                dbds = oForm.DataSources.DBDataSources.Item(DataTable);
                FileName = dbds.GetValue("U_FileName", Offset).ToString().Trim();
                ServerPath = dbds.GetValue("U_FilePath", Offset).ToString().Trim();
                /*非上传文件下载无效*/
                if (string.IsNullOrEmpty(ServerPath))
                {
                    SBOApp.StatusBar.SetText("服务器地址不正确，请与管理员联系。", SAPbouiCOM.BoMessageTime.bmt_Long, SAPbouiCOM.BoStatusBarMessageType.smt_Error);
                    return;

                }
                SAPBoAddon.B1Assistant.WinFormDialogSetting oDialogSetting = new WinFormDialogSetting();
                oDialogSetting.Title = "附件下载";
                oDialogSetting.Filter = "*.*|*.*";
                oDialogSetting.FileName = FileName;
                SAPBoAddon.B1Assistant.WinForm.WinFormDialogSetting = oDialogSetting;
                FilePath = SAPBoAddon.B1Assistant.WinForm.WinForm_GetSaveFileName();
                if (string.IsNullOrEmpty(FilePath)) return;
                SBOApp.StatusBar.SetText("文件正在下载...", SAPbouiCOM.BoMessageTime.bmt_Long, SAPbouiCOM.BoStatusBarMessageType.smt_Warning);
                DownCommand(ServerPath, FilePath);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        ///文件下载
        /// </summary>
        public void DownFile(string FileName, string ServerPath)
        {
            try
            {
                #region 服务器初始化
                string Command = string.Empty;
                string UpLoadFileName = string.Empty;
                string FilePath = string.Empty;
                #endregion
                SAPBoAddon.B1Assistant.WinFormDialogSetting oDialogSetting = new WinFormDialogSetting();
                oDialogSetting.Title = "附件下载";
                oDialogSetting.Filter = "*.*|*.*";
                oDialogSetting.FileName = FileName;
                SAPBoAddon.B1Assistant.WinForm.WinFormDialogSetting = oDialogSetting;
                FilePath = SAPBoAddon.B1Assistant.WinForm.WinForm_GetSaveFileName();
                if (string.IsNullOrEmpty(FilePath)) return;

                /*非上传文件下载无效*/
                if (string.IsNullOrEmpty(ServerPath))
                {
                    SBOApp.StatusBar.SetText("服务器地址不正确，请与管理员联系。", SAPbouiCOM.BoMessageTime.bmt_Long, SAPbouiCOM.BoStatusBarMessageType.smt_Error);
                    return;

                }

                SBOApp.StatusBar.SetText("文件正在下载...", SAPbouiCOM.BoMessageTime.bmt_Long, SAPbouiCOM.BoStatusBarMessageType.smt_Warning);
                DownCommand(ServerPath, FilePath);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void DownCommand(string ServerPath, string FilePath)
        {
#if DEBUG
            DateTime dt1 = DateTime.Now;
#endif
            string Command = string.Empty;
            #region 拼接命令字符串
            //连接服务器
            ConnectionServer();
            //copy文件
            CopyFile(ServerPath, FilePath);
            //关闭连接
            CloseConection();
            #endregion
#if DEBUG
            TimeSpan ts = DateTime.Now - dt1;
            SBOApp.SetStatusBarMessage("附件下载耗时：" + ts.TotalMilliseconds.ToString(), SAPbouiCOM.BoMessageTime.bmt_Short, false);
#endif
            if (SBOApp.MessageBox("文件下载成功！\r\n是否打开文件?", 2, "是", "否") == 1)
            {
                Command = "Call \"" + FilePath + "\"";
                string Error = string.Empty;
                string Result = string.Empty;
                FileUploading.Execute(Command, 60 * 1000, out Result, out Error);
                if (string.IsNullOrEmpty(Error) == false)
                {
                    throw new Exception("系统不支持此格式或文件不存在。错误信息：" + Error);
                }
            }

        }
        #endregion
        /// <summary>
        /// 下载按钮是否可以显示
        /// </summary>
        /// <param name="oForm"></param>
        public void DownButtonVisable(SAPbouiCOM.Form oForm, string DataTable, int Offset, bool FormMode = true)
        {
            if (FormMode)
            {
                if (oForm.Mode == SAPbouiCOM.BoFormMode.fm_OK_MODE || oForm.Mode == SAPbouiCOM.BoFormMode.fm_VIEW_MODE)
                {
                    SAPbouiCOM.DBDataSource dbds = oForm.DataSources.DBDataSources.Item(DataTable);
                    if (string.IsNullOrEmpty(dbds.GetValue("U_FilePath", Offset).Trim()))
                    {
                        oForm.Items.Item("Down").Visible = false;
                    }
                    else
                    {
                        oForm.Items.Item("Down").Visible = true;
                    }
                }
            }
            else
            {
                SAPbouiCOM.DBDataSource dbds = oForm.DataSources.DBDataSources.Item(DataTable);
                if (string.IsNullOrEmpty(dbds.GetValue("U_FilePath", Offset).Trim()))
                {
                    oForm.Items.Item("Down").Visible = false;
                }
                else
                {
                    oForm.Items.Item("Down").Visible = true;
                }
            }
        }
        #endregion

        #region  辅助函数
        /// <summary>
        /// 获取填充‘0’后的字符流水号
        /// </summary>
        private string GetSerialNum(int totalLength, object val)
        {
            string str_leftzero = string.Empty;
            string str_Val = string.Empty;
            for (int i = 0; i < totalLength; i++)
            {
                str_leftzero += "0";
            }
            str_Val = str_leftzero + val.ToString();
            return str_Val.Substring(str_Val.Length - totalLength);
        }
        /// <summary>
        /// 生成服务器文件名
        /// </summary>
        private string CreateFileName(SAPbouiCOM.DBDataSource dbds, SAPbouiCOM.Form CurrentForm)
        {
            string ServerPath = string.Empty;
            string cFormType = CurrentForm.TypeEx;
            /*目标文件夹*/
            string ServerTargetFile = CurrentForm.TypeEx;

            string FilePrefix = "UL_" + cFormType.Substring(cFormType.LastIndexOf("_") + 1);
            string show_FileName = string.Empty;
            string FileName = string.Empty;
            string FilePath = string.Empty;
            string UpLoadFileName = dbds.GetValue("U_LocalPath", dbds.Offset).Trim();
            string DocEntry = SAPBoAddon.B1Assistant.Item.GetValue(CurrentForm, CurrentForm.DataBrowser.BrowseBy).ToString().Trim();

            /*检查是否存在文件夹*/
            ServerPath = string.Format(@"\\{0}\{1}\{2}", ServerIP, ServerUpLoadFilePath, ServerTargetFile);
            ////if (!System.IO.File.Exists(ServerPath))
            ////{
            ////    System.IO.Directory.CreateDirectory(ServerPath);
            ////}
            /*上传文件命名规则   如：UL_Delegate 000101.doc*/
            string LineId = dbds.GetValue("LineId", dbds.Offset).Trim();
            FileName = FilePrefix + " " + this.GetSerialNum(4, DocEntry) + this.GetSerialNum(2, LineId) + UpLoadFileName.Substring(UpLoadFileName.LastIndexOf("."));
            FilePath = ServerPath + "\\" + FileName;
            return FilePath;
        }

        #endregion
        /// <summary>
        /// 设置附件基本信息
        /// </summary>
        /// <param name="dbds"></param>
        /// <param name="clientPath"></param>
        public void SetAffixInfo(SAPbouiCOM.Form curForm, string DataTable, int Offset)
        {
            SAPbouiCOM.DBDataSource dbds = curForm.DataSources.DBDataSources.Item(DataTable);
            string FilePath = string.Empty;
            FilePath = SAPBoAddon.B1Assistant.WinForm.WinForm_GetOpenFileName();
            if (string.IsNullOrEmpty(FilePath) == false)
            {
                dbds.SetValue("U_LocalPath", Offset, FilePath);
                string UpLoadFileName = FilePath.Substring(FilePath.LastIndexOf(@"\") + 1);
                dbds.SetValue("U_FileName", Offset, UpLoadFileName);
                dbds.SetValue("U_CreateTime", Offset, DateTime.Now.ToString("yyyy-MM-dd  HH:mm:ss"));
                dbds.SetValue("U_Creator", Offset, SBOCompany.UserName);
                string serverFileName = this.CreateFileName(dbds, curForm);
                dbds.SetValue("U_FilePath", Offset, serverFileName);
                /*如果确定状态则手动置为更新状态*/
                if (curForm.Mode == SAPbouiCOM.BoFormMode.fm_OK_MODE)
                {
                    curForm.Mode = SAPbouiCOM.BoFormMode.fm_UPDATE_MODE;
                }
            }
        }
    }
    public class FileUploading
    {
        ///// <summary>
        ///// 执行DOS命令，返回DOS命令的输出
        ///// </summary>
        ///// <param name="Command">dos命令</param>
        ///// <returns>返回输出，如果发生异常，返回空字符串</returns>
        //public static string Execute(string Command)
        //{
        //    return Execute(Command, 60 * 1000);
        //}
        /// <summary>
        /// 执行DOS命令，返回DOS命令的输出
        /// </summary>
        /// <param name="Command">dos命令</param>
        /// <param name="milliseconds">等待命令执行的时间（单位：毫秒），如果设定为0，则无限等待</param>
        /// <returns>返回输出，如果发生异常，返回空字符串</returns>
        public static void Execute(string Command, int milliseconds, out string Result, out string Error)
        {
            string StandardOutput = string.Empty;     //输出字符串
            string StandardError = string.Empty;
            if (Command != null && Command != "")
            {
                Process myProcess = new Process();     //创建进程对象
                ProcessStartInfo myStartInfo = new ProcessStartInfo();
                myStartInfo.FileName = "cmd.exe";      //设定需要执行的命令
                myStartInfo.Arguments = "/C " + Command;   //设定参数，其中的“/C”表示执行完命令后马上退出
                myStartInfo.UseShellExecute = false;     //不使用系统外壳程序启动
                myStartInfo.RedirectStandardInput = false;   //不重定向输入
                myStartInfo.RedirectStandardOutput = true;   //重定向输出
                myStartInfo.RedirectStandardError = true;//重定向错误信息
                myStartInfo.CreateNoWindow = true;     //不创建窗口
                myProcess.StartInfo = myStartInfo;
                try
                {
                    if (myProcess.Start())       //开始进程
                    {
                        if (milliseconds == 0)
                            myProcess.WaitForExit();     //这里无限等待进程结束
                        else
                            myProcess.WaitForExit(milliseconds);  //这里等待进程结束，等待时间为指定的毫秒
                        StandardOutput = myProcess.StandardOutput.ReadToEnd();//读取进程的输出
                        StandardError = myProcess.StandardError.ReadToEnd();
                    }
                }
                catch
                {
                }
                finally
                {
                    if (myProcess != null)
                    {
                        myProcess.Close();
                        myProcess.Dispose();
                    }
                }
            }
            Result = StandardOutput;
            Error = StandardError;
        }
    }
}